﻿// Gateway.Api 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
// 
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
// 
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using System.Diagnostics;
using Aurora.AI.Abstractions;
using Aurora.AI.Abstractions.Chats;
using Aurora.AI.Abstractions.Chats.Dtos;
using Aurora.AI.Claudia;
using Aurora.AI.Common;
using Aurora.AI.Common.Extensions;
using Aurora.AI.Hunyuan;
using Aurora.AI.OpenAI;
using Aurora.AI.SparkDesk;
using Microsoft.Extensions.DependencyInjection;

namespace Aurora.AI.Gateway.Services.ChatChannel;

public class ChannelTestService(ChatChannelService channelService, IServiceProvider serviceProvider)
{
    /// <summary>
    /// 测试
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentException"></exception>
    public async Task<long> Test(string id)
    {
        var channel = await channelService.GetById(id);
        if (channel == null)
        {
            throw new ArgumentException("渠道不存在");
        }

        IAuroraAIChatCompletionsService chatCompletionsService =
            serviceProvider.GetKeyedService<IAuroraAIChatCompletionsService>(channel.Type);
        if (chatCompletionsService == null)
        {
            throw new ArgumentException("渠道服务不存在");
        }

        var chatRequest = new AuroraAIChatCompletionsRequest()
        {
            TopP = 0.7f,
            Temperature = 0.95f,
            Messages = new List<AuroraAIChatMessage>()
            {
                AuroraAIChatMessage.CreateUserMessage("hello")
            }
        };
        var platformOptions = new AuroraAIPlatformOptions()
        {
            Address = channel.Address,
            ApiKey = channel.Key,
            Other = channel.Other
        };
        if (channel.Type == OpenAIPlatformOptions.PlatformCode)
        {
            // 获取渠道是否支持gpt-3.5-turbo
            chatRequest.Model = AuroraAIJsonSerializer.Deserialize<List<string>>(channel.Models).Order()
                .FirstOrDefault(x => x.StartsWith("gpt-", StringComparison.OrdinalIgnoreCase));
        }
        else if (channel.Type == ClaudiaPlatformOptions.PlatformCode)
        {
            chatRequest.Model =
                AuroraAIJsonSerializer.Deserialize<List<string>>(channel.Models)
                    .FirstOrDefault(x => x.StartsWith("claude", StringComparison.OrdinalIgnoreCase));
        }
        else if (channel.Type == SparkDeskPlatformOptions.PlatformCode)
        {
            chatRequest.Model = AuroraAIJsonSerializer.Deserialize<List<string>>(channel.Models).FirstOrDefault(x =>
                x.StartsWith("general", StringComparison.OrdinalIgnoreCase) ||
                x.StartsWith("SparkDesk", StringComparison.OrdinalIgnoreCase));
        }
        else if (channel.Type == HunyuanPlatformOptions.PlatformCode)
        {
            chatRequest.Model =
                AuroraAIJsonSerializer.Deserialize<List<string>>(channel.Models)
                    .FirstOrDefault(x => !x.Contains("embedding", StringComparison.OrdinalIgnoreCase));
        }
        else
        {
            chatRequest.Model = AuroraAIJsonSerializer.Deserialize<List<string>>(channel.Models).FirstOrDefault();
        }

        if (string.IsNullOrEmpty(chatRequest.Model))
        {
            chatRequest.Model = AuroraAIJsonSerializer.Deserialize<List<string>>(channel.Models).FirstOrDefault();
        }

        // 写一个10s的超时
        var token = new CancellationTokenSource();
        var sw = Stopwatch.StartNew();
        var circuitBreaker = new CircuitBreaker(3, TimeSpan.FromSeconds(10));
        AuroraAIChatCompletionsResponse response = null;
        await circuitBreaker.ExecuteAsync(
            async () =>
            {
                try
                {
                    response = await chatCompletionsService.ChatCompletionsAsync(chatRequest, platformOptions, token.Token);
                }
                catch (Exception e)
                {

                    response = new AuroraAIChatCompletionsResponse
                    {
                        Error = new Abstractions.Dtos.AuroraAIError { Message = e.Message }
                    };
                }
                
            }, 3, 500);
        sw.Stop();
        // 更新渠道测试响应时间

        await channelService.UpdateResponseTime(channel.Id, sw.ElapsedMilliseconds);
        if (!string.IsNullOrEmpty(response?.Error?.Message))
        {
            throw new ArgumentException(response.Error?.Message);
        }

        return (response?.Choices?.Count > 0) ? sw.ElapsedMilliseconds : -1;
    }
}